package edu.vt.ece.rt.quorum.tree;

import java.util.ArrayList;
import java.util.List;

import edu.vt.ece.rt.util.Logger.Logger;

public class Tree{
	public Node root;
//	public int childCount;
	public int level;			
	public ArrayList<Tree> childList;
	public int degree;
	
	public Tree(Node n, int degree){
		this.root = n;
		childList = new ArrayList<Tree>();
		this.degree = degree;
	}

	//FIXME: Clean It up
	public static Tree createTree(List<Node> l, int degree){
		
		if(l == null || l.size() == 0){
			return null;
		}

		ArrayList<Tree> currLevelTrees = new ArrayList<Tree>();
		int level = 0;
		currLevelTrees.add(new Tree(l.remove(0), degree));
		//Modified by Sudhanshu
		Tree retTree =  currLevelTrees.get(0);
		retTree.level = 0;
		
		while (l.size() != 0) {

			int sizeCurrLevel = currLevelTrees.size();
			ArrayList<Tree> nextLevelTrees = new ArrayList<Tree>();
			// go over lowest level and fill them up
			for (int j = 0; j < sizeCurrLevel; j++) {
				Tree currTree = currLevelTrees.get(j);
				if (level == 0) retTree = currTree;
				currTree.level = level;
				currTree.addNode(degree, l, nextLevelTrees);
			}
			
			// update the latest lowest level created
			currLevelTrees = nextLevelTrees;
			level++;
		}
		
		return retTree;
	}
	
	
	public void addNode(int degree, List<Node> l, ArrayList<Tree> nextLevelTrees) {
		for (int i = 0; i < degree; i++) {
			if (l.size() > 0) {
				Logger.debug("Adding "+l.get(0).address +" to "+this.root.address);
				Node n = l.remove(0);
				Tree currTree = new Tree(n, degree); 
				childList.add(currTree);
				nextLevelTrees.add(nextLevelTrees.size(), currTree);
			}	
		}
	}
	
	public void print() {			
		System.out.println(this.root.val);
		for (int i = 0; i < this.childList.size(); i++) {			
			childList.get(i).print();
		}
	}
	

	public boolean addMajorityChildren(ArrayList<Node> quorumList ,
										ArrayList<Tree>  failures) {
		
		int majority = degree/2 + 1;
		int nodesAdded = 0;
		for (int i = 0; i < childList.size(); i++) {
						
			Tree currTree = childList.get(i);
			Node n = currTree.root;
			if (n.isRunning()) {
				quorumList.add(n);
				nodesAdded++;
			} else {
				failures.add(currTree);
			}
			
			if (nodesAdded == majority) return true;
		}
		
		return false;
	}


	public static void main(String[] args) {
		ArrayList<Node> l= new ArrayList<Node>();
		for(int i=0;i<13;i++){
			l.add(new Node(i));
		}
		
		Tree t = Tree.createTree(l, 3);
		
		t.print();
		
	}

	/**
	 * @return
	 */
	public List<Node> getNodeList() {
		// TODO Auto-generated method stub
		return null;
	}
}